package com.cskaoyan.service.wxService;

import com.cskaoyan.bean.*;
import com.cskaoyan.mapper.*;
import com.github.pagehelper.PageHelper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import com.cskaoyan.bean.Order;
import com.cskaoyan.bean.OrderGoods;
import com.cskaoyan.bean.OrderGoodsExample;
import com.cskaoyan.mapper.OrderGoodsMapper;
import com.cskaoyan.mapper.OrderMapper;
import com.github.pagehelper.PageHelper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.lang.System;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class WxOrderServiceImpl implements WxOrderService {

    @Autowired
    OrderMapper orderMapper;
    @Autowired
    OrderGoodsMapper orderGoodsMapper;
//    @Autowired
//    AddressMapper addressMapper;
    @Autowired
    CouponMapper couponMapper;
    @Autowired
    CartMapper cartMapper;
    @Autowired
    CommentMapper commentMapper;

    @Autowired
    AddressMapper addressMapper;

    @Autowired
    SystemMapper systemMapper;

    @Autowired
    RegionMapper regionMapper;


    //shoetype=0:全部；=1：101；=2：201；=3：301；=4：401+commmnt=0/402
    @Override
    public Map<String, Object> orderList(Integer showType, Integer page, Integer size) {
        PageHelper.startPage(page,size);
        Subject subject = SecurityUtils.getSubject();
        Integer userId = (Integer) subject.getPrincipal();
        List<Map<String,Object>> mapList = null;
        if (showType == 4){
            mapList = orderMapper.selectListMapByType4(userId);
        }else if (showType == 0){
            mapList = orderMapper.selectListMapByUserId(userId);
        }else {
            Integer orderStatus = getOrderStatus(showType);
            mapList = orderMapper.selectListMapByOrderStatus(userId,orderStatus);
        }
        for (Map<String, Object> map : mapList) {
            Integer status = (Integer) map.remove("order_status");
            Map<String, Object> handleOption = getHandleOption(status);
            String orderStatusText = getOrderStatusText(status);
            List<Map<String,Object>> goodsList = orderGoodsMapper.selectGoodsMapListByOrderId((Integer) map.get("id"));
            BigDecimal groupon_price = (BigDecimal) map.remove("groupon_price");
            if (groupon_price.intValue() != 0){
                map.put("isGroupin",true);
            }else {
                map.put("isGroupin",false);
            }
            map.put("orderStatusText",orderStatusText);
            map.put("handleOption",handleOption);
            map.put("goodsList",goodsList);
        }
        Integer count = mapList.size();
        Integer totalPage = count%size == 0?(count/size):(count/size+1);
        HashMap<String, Object> map = new HashMap<>();
        map.put("data",mapList);
        map.put("count",count);
        map.put("totalPage",totalPage);
        return map;
    }


    @Override
    public int getOrderComment(Integer orderGoodsId, String content, Short star, boolean hasPicture, String[] picUrls) {
        Comment comment = new Comment();
        OrderGoods orderGoods = orderGoodsMapper.selectByPrimaryKey(orderGoodsId);
        comment.setValueId(orderGoods.getGoodsId());
        byte b = 0;
        comment.setType(b);
        comment.setContent(content);

        Order order = orderMapper.selectByPrimaryKey(orderGoods.getOrderId());
        comment.setUserId(order.getUserId());
        comment.setHasPicture(hasPicture);
        comment.setPicUrls(picUrls);
        comment.setStar(star);
        comment.setAddTime(new Date());
        comment.setUpdateTime(new Date());
        comment.setDeleted(false);
        int i = commentMapper.insertSelective(comment);
        OrderGoodsExample orderGoodsExample = new OrderGoodsExample();
        orderGoodsExample.createCriteria().andGoodsIdEqualTo(orderGoodsId);
        orderGoods.setComment(comment.getId());
        orderGoodsMapper.updateByPrimaryKeySelective(orderGoods);
        OrderExample orderExample = new OrderExample();
        orderExample.createCriteria().andIdEqualTo(order.getId());
        Integer orderComment = order.getComments() + 1;
        Short orderComment1 = orderComment.shortValue();
        order.setComments(orderComment1);
        orderMapper.updateByPrimaryKeySelective(order);
        return i;

    }



//    @Override
//    public Integer submitWxOrder(Map<String, Object> map) {
//
//        Subject subject = SecurityUtils.getSubject();
//        Integer userId = (Integer) subject.getPrincipal();
//        Date date = new Date();
//        String order_sn = date.toString();
//        //cart
//        Integer orderStatus = 201;
//        Address address_now = addressMapper.selectByPrimaryKey((Integer) map.get("adressId"));
//        Integer cartId = (Integer) map.get("cartId");
//        Cart cart = null;
//        if (cartId != 0){
//            cart = cartMapper.selectByPrimaryKey(cartId);
//        }else {
//            CartExample cartExample = new CartExample();
//            CartExample.Criteria criteria = cartExample.createCriteria();
//            criteria.andNumberEqualTo((short) 1);
//            criteria.andUserIdEqualTo(userId);
//            List<Cart> cartList = cartMapper.selectByExample(cartExample);
//        }
//
//        String consignee = address_now.getName();
//        String mobile = address_now.getMobile();
//        String address = address_now.getAddress();
//        String message = String.valueOf(map.get("message"));
//        Integer couponId = (Integer)map.get("couponId");
//        if (couponId != 0){
//            Coupon coupon = couponMapper.selectByPrimaryKey(couponId);
//            BigDecimal min = coupon.getMin();
//
//        }
//
//        return null;
//    }


    @Override
    public OrderGoods ordergoods(Integer orderId, Integer goodsId) {
        OrderGoodsExample orderGoodsExample = new OrderGoodsExample();
        OrderGoodsExample.Criteria criteria = orderGoodsExample.createCriteria();
        criteria.andOrderIdEqualTo(orderId);
        criteria.andGoodsIdEqualTo(goodsId);
        List<OrderGoods> list = orderGoodsMapper.selectByExample(orderGoodsExample);
        OrderGoods orderGoods = orderGoodsMapper.selectByPrimaryKey(orderId);
        return orderGoods;
    }

    @Override
    public Map<String, Object> orderDetail(Integer orderId) {

        Map<String,Object> map = orderMapper.selectOrderMapByOrderId(orderId);
        Integer status = (Integer) map.remove("order_status");
        Map<String, Object> handleOption = getHandleOption(status);
        String orderStatusText = getOrderStatusText(status);
        map.put("handleOption",handleOption);
        map.put("orderStatusText",orderStatusText);
        OrderGoodsExample orderGoodsExample = new OrderGoodsExample();
        OrderGoodsExample.Criteria criteria = orderGoodsExample.createCriteria();
        criteria.andOrderIdEqualTo(orderId);
        List<OrderGoods> orderGoods = orderGoodsMapper.selectByExample(orderGoodsExample);
        HashMap<String, Object> data = new HashMap<>();
        data.put("orderInfo",map);
        data.put("orderGoods",orderGoods);
        return data;
    }

    @Override
    public void deleteWxOrder(Integer orderId) {

        //order
        Order order = new Order();
        order.setId(orderId);
        order.setDeleted(true);
        order.setUpdateTime(new Date());
        //order_goods
        OrderGoods orderGoods = new OrderGoods();
        orderGoods.setOrderId(orderId);
        orderGoods.setDeleted(true);
        orderGoods.setUpdateTime(new Date());
        OrderGoodsExample orderGoodsExample = new OrderGoodsExample();
        OrderGoodsExample.Criteria criteria = orderGoodsExample.createCriteria();
        criteria.andOrderIdEqualTo(orderId);
        orderMapper.updateByPrimaryKeySelective(order);
        orderGoodsMapper.updateByExampleSelective(orderGoods,orderGoodsExample);
    }

    @Override
    public void confirmWxOrder(Integer orderId) {
        Order order = new Order();
        order.setId(orderId);
        order.setOrderStatus(401);
        order.setUpdateTime(new Date());
        orderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    public void refundWxOrder(Integer orderId) {
        Order order = new Order();
        order.setId(orderId);
        order.setOrderStatus(202);
        order.setUpdateTime(new Date());
        orderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    public void cancelWxOrder(Integer orderId) {
        Order order = new Order();
        order.setId(orderId);
        order.setOrderStatus(102);
        order.setUpdateTime(new Date());
        orderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    public void wxOrderComment(Map<String, Object> map) {
        Subject subject = SecurityUtils.getSubject();
        Integer userId = (Integer) subject.getPrincipal();
        Date date = new Date();
        OrderGoods orderGoods = orderGoodsMapper.selectByPrimaryKey((Integer) map.get("orderGoodsId"));
        Integer type = 0;
        String str = map.get("picUrls").toString();
        String[] picUrl = str.split(",");
        Integer intStar = (Integer) map.get("star");
        short star = intStar.shortValue();
        Comment comment = new Comment(null,orderGoods.getGoodsId(), type.byteValue(),
                                        (String) map.get("content"),userId,
                                        (Boolean) map.get("hasPicture"),
                                         picUrl, star,date,
                                        date,false);
        commentMapper.insertSelective(comment);
        orderGoods.setComment(comment.getId());
        orderGoods.setUpdateTime(date);
        orderGoodsMapper.updateByPrimaryKey(orderGoods);
    }


    public Map<String,Object> getHandleOption(Integer status){
        Map<String, Object> map = new HashMap<>();
        //未取消
        map.put("cancel",false);
        //可删除
        map.put("delete",false);
        //已支付
        map.put("pay",false);
        //不可评论
        map.put("comment",false);
        //已确认
        map.put("confirm",false);
        //已收货
        map.put("refund",false);
        //可以再次购买
        map.put("rebuy",false);
        switch (status){
            case 101:
                map.put("cancel",true);
                map.put("pay",true);
                break;
            case 102:
            case 103:
                map.put("delete",true);
                break;
            case 201:
                map.put("refund",true);
                break;
            case 202:
                break;
            case 203:
                map.put("delete",true);
                break;
            case 301:
                map.put("confirm",true);
                break;
            case 401:
                map.put("delete",true);
                map.put("comment",true);
                map.put("rebuy",true);
                break;
            case 402:
                map.put("delete",true);
                map.put("rebuy",true);
                break;
            default:
                break;
        }
        return map;
    }
    public String getOrderStatusText(Integer status){
        String orderStatusText = null;
        switch (status){
            case 101:
                orderStatusText = "代付款";
                break;
            case 102:
            case 103:
                orderStatusText = "已取消";
                break;
            case 201:
                orderStatusText = "待发货";
            case 202:
                orderStatusText = "订单取消，退款中";
            case 203:
                orderStatusText = "退款成功";
            case 301:
                orderStatusText = "已发货";
            case 401:
            case 402:
                orderStatusText = "待评价";
            default:
                break;
        }
        return orderStatusText;
    }
    private Integer getOrderStatus(Integer showType) {
        Integer orderStatus = null;
        switch (showType){
            case 1:
                orderStatus = 101;
                break;
            case 2:
                orderStatus = 201;
                break;
            case 3:
                orderStatus = 301;
                break;
            default:
                break;
        }
        return orderStatus;
    }

    @Override
    public Integer OrderSubmit(Integer addressId, Integer couponId, Integer cartId) {
        Address address = addressMapper.selectByPrimaryKey(addressId);
        Integer userId = address.getUserId();
        if (cartId == 0) {
            CartExample cartExample = new CartExample();
            cartExample.createCriteria().andUserIdEqualTo(userId).andCheckedEqualTo(true).andDeletedEqualTo(false);
            List<Cart> carts = cartMapper.selectByExample(cartExample);
            Integer orderId = createOrder(address, carts, couponId);
            createOrderGoods(orderId, carts);
            return orderId;
        } else {
            Cart cart = cartMapper.selectByPrimaryKey(cartId);
            List<Cart> cartList = new ArrayList<>();
            cartList.add(cart);
            Integer orderId = createOrder(address, cartList, couponId);
            createOrderGoods(orderId, cartList);
            return orderId;
        }
    }


    private Integer createOrder(Address address, List<Cart> cartList, Integer couponId) {

        Coupon coupon = couponMapper.selectByPrimaryKey(couponId);
        Order order = new Order();
        //地址赋值，改变订单状态
        order.setUserId(address.getUserId());
        order.setConsignee(address.getName());
        order.setOrderSn(createOrderSn());
        Integer status = 101;
        order.setOrderStatus(status);
        order.setMobile(address.getMobile());
        order.setAddress(getDetailedAddress(address));

        //商品价格
        BigDecimal orderGoodsPrice = getOrderGoodsPrice(address.getUserId(), cartList);
        order.setGoodsPrice(orderGoodsPrice);

        //邮费
        String s1= "cskaoyan_mall_express_freight_min";
        String s2="cskaoyan_mall_express_freight_value";
        SystemExample systemExample1 = new SystemExample();
        SystemExample systemExample2 = new SystemExample();
        systemExample1.createCriteria().andKeyNameEqualTo(s1);
        systemExample2.createCriteria().andKeyNameEqualTo(s2);
        List<com.cskaoyan.bean.System> systems1 = systemMapper.selectByExample(systemExample1);
        String keyValue = systems1.get(0).getKeyValue();
        List<com.cskaoyan.bean.System> systems2 = systemMapper.selectByExample(systemExample2);
        String keyValue1 = systems2.get(0).getKeyValue();

        int i1 = orderGoodsPrice.intValue();
        int s1I = Integer.parseInt(keyValue);
        BigDecimal freightPrice =null;
        if (i1 > s1I){
            freightPrice = new BigDecimal(0);
        }else {
            freightPrice = new BigDecimal(keyValue1);
        }
        order.setFreightPrice(freightPrice);

        //优惠券减免
        BigDecimal couponPrice = null;
        BigDecimal groupOnPrice = new BigDecimal(0);
        if (coupon != null) {
            couponPrice = coupon.getDiscount();
            //变更优惠券使用状态
            CouponExample couponExample = new CouponExample();
            couponExample.createCriteria().andDeletedEqualTo(true);
            couponMapper.deleteByExample(couponExample);
        } else {
            couponPrice = new BigDecimal(0);
        }
        order.setCouponPrice(couponPrice);

        //积分优惠价格
        BigDecimal integralPrice = new BigDecimal(1);
        order.setIntegralPrice(integralPrice);

        //订单价格
        BigDecimal orderPrice = orderGoodsPrice.add(freightPrice);
        BigDecimal actualPrice = orderPrice.subtract(couponPrice).subtract(integralPrice);
        order.setOrderPrice(orderPrice);
        order.setActualPrice(actualPrice);
        order.setAddTime(new Date());
        order.setUpdateTime(new Date());
        order.setDeleted(false);
        order.setGrouponPrice(groupOnPrice);
        System.out.println(order.getId());

        int i = orderMapper.insertSelective(order);
        return order.getId();
    }


    private void createOrderGoods(Integer orderId, List<Cart> cartList) {
        if (cartList == null) {
            return;
        }
        for (Cart c : cartList) {
            OrderGoods orderGoods = new OrderGoods();
            orderGoods.setOrderId(orderId);
            orderGoods.setGoodsId(c.getGoodsId());
            orderGoods.setGoodsName(c.getGoodsName());
            orderGoods.setGoodsSn(c.getGoodsSn());
            orderGoods.setProductId(c.getProductId());
            orderGoods.setNumber(c.getNumber());
            orderGoods.setPrice(c.getPrice());
            orderGoods.setSpecifications(c.getSpecifications());
            orderGoods.setPicUrl(c.getPicUrl());
            orderGoods.setComment(0);
            orderGoods.setAddTime(new Date());
            orderGoods.setUpdateTime(new Date());
            orderGoods.setDeleted(false);
            orderGoodsMapper.insertSelective(orderGoods);
            //清空对应购物车内容
            cartMapper.deleteByPrimaryKey(c.getId());
        }

    }

    private BigDecimal getOrderGoodsPrice(Integer userId, List<Cart> cartList) {
        BigDecimal orderPrice = new BigDecimal(0);
        CartExample cartExample = new CartExample();
        for (Cart c : cartList) {
            BigDecimal price = new BigDecimal(c.getPrice().toString());
            BigDecimal num = new BigDecimal(c.getNumber().toString());
            orderPrice = orderPrice.add(price.multiply(num));
        }
        return orderPrice;
    }

    private String createOrderSn() {
        Long timeStamp = System.currentTimeMillis();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String newOrderSnPre = sdf.format(new Date(Long.parseLong(String.valueOf(timeStamp))));
        Random random = new Random();
        int i = random.nextInt(999999);
        Integer integer = new Integer(i);
        String newOrderSnPost = integer.toString();
        String newOrderSn = newOrderSnPre + newOrderSnPost;
        return newOrderSn;
    }

    private String getDetailedAddress(Address address) {
        Region province = regionMapper.selectByPrimaryKey(address.getProvinceId());
        Region city = regionMapper.selectByPrimaryKey(address.getCityId());
        Region area = regionMapper.selectByPrimaryKey(address.getAreaId());
        String detailedAddress = province.getName() + " " + city.getName() + " " + area.getName() + " " + address.getAddress();
        return detailedAddress;
    }

}
